package com.ideabove.heart.manager;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;

import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;

import com.ideabove.heart.AlarmSetActivity;
import com.ideabove.heart.MainActivity;
import com.ideabove.heart.MoeActivity;
import com.ideabove.heart.MoeIntroActivity;
import com.ideabove.heart.alarm.AlarmReceiver;
import com.ideabove.heart.data.Comment;
import com.ideabove.heart.data.Episode;
import com.ideabove.heart.db.DBHelper;
import com.ideabove.heart.db.Database;
import com.ideabove.heart.schedule.ScheduleImpl;
import com.ideabove.heart.schedule.ScheduleInfo;
import com.ideabove.heart.util.LogUtil;

/**
 * 두근두근 알람의 스토리와 어떤 화면을 띠워야 하는지를 관리하는 메니져
 * 스케줄을 알려주고 그것을 띠우는 역활을 하고 있다.
 * 현제 스케줄이 어떤것인지 다음 스케줄이 어떤것인지를 관리함.
 * @author bill
 *
 */
public class ScheduleManager {

	private Activity activity;
	public interface Schedule{
		public void connect();
		public void prepare();
		public void display();
		public void pause();
		public void done();
		public void doIt();
	}
	
	private static int ARARM_INDEX = 337213;
	private static int ARARM_INDEX_2 = 3372155; 
	
	public static final int NO_CREATE_SCHEDULE = 0;
	public static final int STORY_START = 1;
	public static final int STORY_DONE = 2;
	
	public static String PREFERENCE_DRESS_KEY = "com.ideabove.heart:dress";
	public static String PREFERENCE_DRESS_DEFAULT = "com.ideabove.heart:dress_default";
	public static String PREFERENCE_HAIR_DEFAULT = "com.ideabove.heart:dress_hair";
	
	public static String PREFERENCE_SETTING = "com.ideabove.heart:setting";
	public static String PREFERENCE_BG_SOUND = "com.ideabove.heart:bg_sound";
	public static String PREFERENCE_VOICE_SOUND = "com.ideabove.heart:voice_sound";
	public static String PREFERENCE_TEXT_ONOFF = "com.ideabove.heart:text_onoff";
	public static String PREFERENCE_STORY_ONOFF = "com.ideabove.heart:story_onoff";

	ArrayList <Schedule>schedule;


	public ScheduleManager(Activity activity){
		this.activity = activity;
	}
	

	public Schedule whereAmI(DBHelper dbHelper){
		ScheduleInfo scheInfo = dbHelper.getScheduleInfo(); // 현재  몇번째 스케줄이 진행되었는지를 가져옴.
		return makeSchedule(scheInfo);
	}
	
	public Episode getNextEpisodeInfo(Context mCurContext){
		DBHelper dbHelper = new DBHelper(mCurContext);
		ScheduleInfo lastScheInfo = dbHelper.getScheduleInfo(); // 현재  몇번째 스케줄이 진행되었는지를 가져옴.
		
		LogUtil.e("###Next" + lastScheInfo.getNextEp());
		
		return getEpisodeInfo(mCurContext, lastScheInfo.getNextEp());
	}
	
	public Episode getEpisodeInfo(Context mCurContext){
		DBHelper dbHelper = new DBHelper(mCurContext);
		ScheduleInfo lastScheInfo = dbHelper.getScheduleInfo(); // 현재  몇번째 스케줄이 진행되었는지를 가져옴.
		return getEpisodeInfo(mCurContext, lastScheInfo.getEp());
	}
	
	// 에피소드별 케릭터의 정보를 가져옴.
	public Episode getEpisodeInfo(Context mCurContext ,String fName){
		
		// db open
		DBHelper dbHelper = new DBHelper(mCurContext).open();		
		Episode episode = new Episode();
		ArrayList<Comment> comments = new ArrayList<Comment>();
		try{
			// 에피소드 파일을 DB에 저장된 스탭(에피소드)에 의거 정보를 가져온다.
			String jsonStr = readText(fName);
			
			if(jsonStr != null && jsonStr.length() > 0){			
				try{			
					JSONObject jsonObj = new JSONObject(jsonStr);
					
					episode.setId(jsonObj.getJSONObject("episode").getString("id"));
					if(jsonObj.getJSONObject("episode").has("ep_next")){
						episode.setNextEp(jsonObj.getJSONObject("episode").getString("ep_next"));
					}			
					
					if(jsonObj.getJSONObject("episode").has("rp_img")){
						episode.setRpImg(jsonObj.getJSONObject("episode").getString("rp_img"));
					}
					
					if(jsonObj.getJSONObject("episode").has("bg_sound")){
						episode.setBgSound(jsonObj.getJSONObject("episode").getString("bg_sound"));
					}
					
					JSONArray commentArray = jsonObj.getJSONObject("episode").getJSONArray("comments");

					for (int i = 0; i < commentArray.length(); i++) {
						Comment comnt = new Comment();
						comnt.setVoice(commentArray.getJSONObject(i).getString("voice").toString());
						comnt.setFace(commentArray.getJSONObject(i).getString("face").toString());
						comnt.setHair(commentArray.getJSONObject(i).getString("hair").toString());
						comnt.setDress(commentArray.getJSONObject(i).getString("dress").toString());
						comnt.setBg(commentArray.getJSONObject(i).getString("bg").toString());
						comnt.setComment(commentArray.getJSONObject(i).getString("comment").toString());
						comments.add(comnt);
						
//						LogUtil.e(comnt.getVoice());
//						LogUtil.e(comnt.getFace());
//						LogUtil.e(comnt.getBg());
//						LogUtil.e(comnt.getComment());
					}
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			dbHelper.close();
		}
		episode.setComment(comments);
		return episode;
	}
	public void storyInit(){
		DBHelper helper = new DBHelper(activity);		
//		helper.deleteSchedule();
		helper.initSchedule();
	}
	
	public void insertNextEpisode(long time, int step){		
		DBHelper helper = new DBHelper(activity);		
		Episode episode = getNextEpisodeInfo(activity);		
		helper.insertNextSchedule(time,step,episode.getId(), episode.getNextEp(), episode.getRpImg());
	}
	
	public void episodeStart(){
		DBHelper helper = new DBHelper(activity).open();
		helper.updateSchedule(helper.getLastSchedule().getId(), 0, ScheduleManager.STORY_START);
	}
	
	public void episodeDone(){
		DBHelper helper = new DBHelper(MoeManager.mCurContext).open();
		helper.episodeDone();
	}

	public void doIt(){

	}
	
	public ArrayList<ScheduleInfo> getScheduleInfoList(){
		DBHelper helper = new DBHelper(activity).open();
		return helper.getScheduleInfoList();
	}
	

	public ScheduleInfo getLastSchedule(){
		DBHelper helper = new DBHelper(activity);
		return helper.getLastSchedule();
	}
	
	
	private String readText(String file) throws IOException {
		InputStream is = activity.getAssets().open("episoide/"+file);

		int size = is.available();
		byte[] buffer = new byte[size];
		is.read(buffer);
		is.close();

		String text = new String(buffer);

		return text;
	}

	public Schedule makeSchedule(ScheduleInfo info){

		if(info.getId() == -1){ // 스케줄이 세팅이 안되있다. 처음유저임
			ScheduleImpl sImpl = new ScheduleImpl(){
				public void doIt(){
					new Thread(){
						public void run(){
							try {
								Thread.sleep(2000);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							Intent intent = new Intent(activity, AlarmSetActivity.class);
							activity.startActivity(intent);
							activity.finish();
						}
					}.start();
				}
			};
			return (Schedule) sImpl;
		}else{			
			switch(info.getStep()){
				case NO_CREATE_SCHEDULE: // 알람을 세팅을 했지만 스케쥴이 진행된게 전혀 없는 상태
					ScheduleImpl sImpl = new ScheduleImpl(){
						public void doIt(){
							Intent intent = new Intent(activity, AlarmSetActivity.class);
							activity.startActivity(intent);
							activity.finish();							
						}
					};
					return sImpl;
				case STORY_START: // 처음전화오고 받으면 인트로 걸이 화면에 보임..					
//					activity.finish();
//					Intent intent = new Intent(activity, MoeActivity.class);
//					activity.startActivity(intent);					
//					return new ScheduleImpl();
					
				case STORY_DONE: // 완료후에 					
				
					sImpl = new ScheduleImpl(){
						public void doIt(){							
							Intent iAlarm = new Intent(activity, MainActivity.class);
							iAlarm.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
							activity.startActivity(iAlarm);
							activity.finish();
						}
					};					
					return sImpl;
			}
			
			return null;
		}
	}
	// 부재중인지 아닌지
	public boolean isMissedCall(){
		Hashtable<String, String> info = getAlarmInfo();
		
		if(info.get(Database.AlarmSetTable.REPEATE) == null){
			return false;
		}
		int repeatCnt = Integer.parseInt(info.get(Database.AlarmSetTable.REPEATE));
		int failCnt = Integer.parseInt(info.get(Database.AlarmSetTable.FAILCNT));
				
//		LogUtil.e("#Fail#:" + failCnt);
//		LogUtil.e("#Repeat#:" + repeatCnt);
		
		if(failCnt > repeatCnt){ // 실패한 횟수가 정해진 횟수 보다 크다면..
			return true;
		}
		
		return false;		
	}
	
	// 알람중?
	public boolean isAlarming(){
		Hashtable<String, String> info = getAlarmInfo();
		
		if(info.get(Database.AlarmSetTable.REPEATE) == null){
			return false;
		}
		int repeatCnt = Integer.parseInt(info.get(Database.AlarmSetTable.REPEATE));
		int failCnt = Integer.parseInt(info.get(Database.AlarmSetTable.FAILCNT));
				
//		LogUtil.e("#Fail#:" + failCnt);
//		LogUtil.e("#Repeat#:" + repeatCnt);
		
		if(failCnt > 0 && failCnt <= repeatCnt){ // 실패한 횟수가 정해진 횟수 보다 크다면..
			return true;
		}
		
		return false;		
	}
	
	
	
	public Hashtable<String, String> getAlarmInfo(){
		DBHelper dbHelper = new DBHelper(activity);		
		return dbHelper.getAlarmInfo();
	}
	
	
	public void updateAlarmFail(int id, int failCnt){
		DBHelper dbHelper = new DBHelper(activity);		
		dbHelper.updateAlarmFail(id, failCnt);
	}
	
	public void updateAlarmSucess(long sucessTime){
		DBHelper dbHelper = new DBHelper(activity);
		
		dbHelper.updateAlarmFail(1, 0);
		ScheduleInfo info = dbHelper.getLastSchedule();
		dbHelper.updateAlarmSucess(info.getId(), sucessTime);
	}
	
	public void alarmSetDone(long setTime){
		DBHelper dbHelper = new DBHelper(activity);
		
		// 아무런 스케쥴이 없을때 인트로 실행
		if( ScheduleManager.NO_CREATE_SCHEDULE == dbHelper.getLastSchedule().getStep()){
			Intent iAlarm = new Intent(activity, MoeIntroActivity.class);
			iAlarm.addFlags(Intent.FLAG_FROM_BACKGROUND);
			iAlarm.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);   // Added
			iAlarm.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);              
			iAlarm.putExtra("settime", "" + ((AlarmSetActivity)activity).dateTime.getTimeInMillis()); 

			// 알람을 세팅한다.	
			updateAlarm(setTime);
			
			activity.startActivity(iAlarm);   
			activity.finish();
		
		// 	스케쥴이 이미 세팅되어있다면 메인페이지로.
		}else{		
			Hashtable<String,String> alarmInfo = dbHelper.getAlarmInfo();
			
			if("1".equals( alarmInfo.get(Database.AlarmSetTable.ISUSE) )){
				
				// 알람을 세팅한다.	
				updateAlarm(setTime);				
				activity.finish();
				
			}else{
				// 모닝콜이 off 일때
				MoeManager.setWhatWillIdo(MoeManager.MORNING_CALL_OFF);
				
				Intent iAlarm = new Intent(activity, MoeActivity.class);
				activity.startActivity(iAlarm);				
				unregisterAlarm(activity); // 알람취소
				activity.finish();
			}
		}
	}
	
	public static void unregisterAlarm(Context context)
	{
		Intent intent = new Intent();
		PendingIntent sender
		= PendingIntent.getBroadcast(context, ARARM_INDEX, intent, 0);

		AlarmManager manager =
				(AlarmManager)context
				.getSystemService(Context.ALARM_SERVICE);

		manager.cancel(sender);
	}

	
	private void updateAlarm(long settime) {		

//		settime = settime + (60 * 1000 * 60 * 24);
		
        AlarmManager am = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(activity, AlarmReceiver.class);
        
        Date today = new Date();
        today.setTime(settime);
        
        PendingIntent sender = PendingIntent.getBroadcast(
        		activity, ARARM_INDEX, intent, PendingIntent.FLAG_CANCEL_CURRENT);
//      am.setInexactRepeating(AlarmManager.RTC_WAKEUP, dateTime.getTimeInMillis(), 1, pendingIntent);        
//        am.set(
//        	AlarmManager.RTC_WAKEUP,
//        	settime,
//        	sender
//        );
        
        am.setRepeating(
        	AlarmManager.RTC_WAKEUP,
        	settime,
        	AlarmManager.INTERVAL_DAY, sender
        );		
        
        
	}
	
	public void setAlarmJustOneTime(long settime) {		

        AlarmManager am = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(activity, AlarmReceiver.class);
        
        Date today = new Date();
        today.setTime(settime);
        
        PendingIntent sender = PendingIntent.getBroadcast(
        		activity, ARARM_INDEX_2, intent, PendingIntent.FLAG_CANCEL_CURRENT);
//      am.setInexactRepeating(AlarmManager.RTC_WAKEUP, dateTime.getTimeInMillis(), 1, pendingIntent);
        
        am.set(
        	AlarmManager.RTC_WAKEUP,
        	settime,
        	sender
        );               
	}
	
	
	public void resetAlarm(
			int day, int hour, int min, long time, int isuse, int interval, int repeatCnt){
		DBHelper helper = new DBHelper(activity).open();
		helper.resetAlarm(day, hour, min, time, isuse, interval, repeatCnt);
		helper.close();
	}
	
	public void initFailCnt(){
		DBHelper helper = new DBHelper(activity).open();
		helper.updateFailCnt(1,0); // id, failCnt
		helper.close();
	}
	
	public static void setDefaultDress(Activity activity, String dress, String hair){
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_DRESS_KEY, Activity.MODE_PRIVATE ); 
		SharedPreferences.Editor editor = prefs.edit();	
		
//		dress_cardigan- 분홍짧은머리
//		dress_dress- 분홍짧은머리
//		dress_officelady-분홍짧은머리
//		dress_training-분홍짧은머리
//		dress_nurse-분홍간호사머리
//		dress_maid- 파랑메이드머리
//		dress_stripe-하늘고양이머리
//		dress_pajama-노랑짧은머리
//		dress_seethrough-노랑짧은머리
		
		editor.putString(PREFERENCE_DRESS_DEFAULT, dress);
		editor.putString(PREFERENCE_HAIR_DEFAULT, hair);
		
		
		editor.commit();
	}
	
	public static Comment getDefaultDress(Activity activity){
		
		Comment comment = new Comment();
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_DRESS_KEY, Activity.MODE_PRIVATE); 
		comment.setDress( prefs.getString(PREFERENCE_DRESS_DEFAULT, "") );
		comment.setHair(prefs.getString(PREFERENCE_HAIR_DEFAULT, ""));
		
		
		if(comment.getDress() == null || "".equals(comment.getDress())){
			setDefaultDress(activity, "dress_training.png", "hair_normal.png");
			comment.setDress( prefs.getString(PREFERENCE_DRESS_DEFAULT, "") );
			comment.setHair(prefs.getString(PREFERENCE_HAIR_DEFAULT, ""));
		}
		
		return comment;
	}
	
	// 효과음
	public static void setCurrentBgVolume(Activity activity, float volume){
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_SETTING, Activity.MODE_PRIVATE );
		SharedPreferences.Editor editor = prefs.edit();
		
		editor.putFloat(PREFERENCE_BG_SOUND, volume);
		editor.commit();
	}
	
	public static float getCurrentBgVolume(Activity activity){
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_SETTING, Activity.MODE_PRIVATE ); 
		return prefs.getFloat(PREFERENCE_BG_SOUND, 100f);
	}
	
	// 목소리음
	public static void setCurrentVoiceVolume(Activity activity, float volume){
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_SETTING, Activity.MODE_PRIVATE );
		SharedPreferences.Editor editor = prefs.edit();
		
		editor.putFloat(PREFERENCE_VOICE_SOUND, volume);
		editor.commit();
	}
	
	public static float getCurrentVoiceVolume(Activity activity){
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_SETTING, Activity.MODE_PRIVATE ); 
		return prefs.getFloat(PREFERENCE_VOICE_SOUND, 100f);
	}
	
	// 텍스트 on/off
	public static void setTextOnOff(Activity activity, boolean isOn){
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_SETTING, Activity.MODE_PRIVATE );
		SharedPreferences.Editor editor = prefs.edit();
		
		editor.putBoolean(PREFERENCE_TEXT_ONOFF, isOn);
		editor.commit();
	}
	
	public static boolean isTextOnOff(Activity activity){
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_SETTING, Activity.MODE_PRIVATE ); 
		return prefs.getBoolean(PREFERENCE_TEXT_ONOFF, true);
	}
	
	// 스토리 모드 on/off
	public static void setStoryOnOff(Activity activity, boolean isOn){
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_SETTING, Activity.MODE_PRIVATE );
		SharedPreferences.Editor editor = prefs.edit();
		
		editor.putBoolean(PREFERENCE_STORY_ONOFF, isOn);
		editor.commit();
	}
	
	public static boolean getStoryOnOff(Activity activity){
		SharedPreferences prefs = activity.getSharedPreferences(PREFERENCE_SETTING, Activity.MODE_PRIVATE ); 
		return prefs.getBoolean(PREFERENCE_STORY_ONOFF, true);
	}
}
